<!DOCTYPE html>
<html>

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

    <title>Babylon.js sample code</title>

    <!-- Babylon.js -->
    <script src="https://code.jquery.com/pep/0.4.2/pep.min.js"></script>
    <!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.6.2/dat.gui.min.js"></script> -->
    <!-- <script src="https://preview.babylonjs.com/ammo.js"></script> -->
    <!-- <script src="https://preview.babylonjs.com/cannon.js"></script> -->
    <!-- <script src="https://preview.babylonjs.com/Oimo.js"></script> -->
    <!-- <script src="https://preview.babylonjs.com/gltf_validator.js"></script> -->
    <!-- <script src="https://preview.babylonjs.com/earcut.min.js"></script> -->
    <script src="/babylon.js"></script>
    <!-- <script src="https://preview.babylonjs.com/inspector/babylon.inspector.bundle.js"></script> -->
    <script src="/babylonjs.materials.min.js"></script>
    <!-- <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylonjs.proceduralTextures.min.js"></script> -->
    <!-- <script src="https://preview.babylonjs.com/postProcessesLibrary/babylonjs.postProcess.min.js"></script> -->
    <!-- <script src="https://preview.babylonjs.com/loaders/babylonjs.loaders.js"></script> -->
    <!-- <script src="https://preview.babylonjs.com/serializers/babylonjs.serializers.min.js"></script> -->
    <script src="/babylon.gui.min.js"></script>
    <script src="pep.min.js"></script>
<!--         <script src="https://preview.babylonjs.com/ammo.js"></script>
        <script src="https://preview.babylonjs.com/cannon.js"></script>
        <script src="https://preview.babylonjs.com/Oimo.js"></script> -->
    <style>
        html,
        body {
            overflow: hidden;
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
        }
        
        #renderCanvas {
            width: 100%;
            height: 100%;
            touch-action: none;
        }
    </style>
</head>

<body>
    <canvas id="renderCanvas"></canvas>
    <script>
        function vecToLocal(vector, mesh) {
            var m = mesh.getWorldMatrix();
            var v = BABYLON.Vector3.TransformCoordinates(vector, m);
            return v;
        }

        var canvas = document.getElementById("renderCanvas");
        var engine = new BABYLON.Engine(canvas, true);
        engine.setHardwareScalingLevel(0.6);
        var createScene = function() {
            var runNum = 0;
            var boxSize = 2.5; //盒子大小
            var offset = 0.5 * boxSize; //每格偏移量
            var x_array = [-4, -3, -2, -1, 0, 1, 2, 3, -4, 0, 3, -4, -2, 0, 3, -4, 3, -4, -2, 0, 3, -4, 0, 3, -4, -3, -2, -1, 0, 3,
                0, 1, 2, 3
            ];
            var z_array = [4, 4, 4, 4, 4, 4, 4, 4,
                3, 3, 3,
                2, 2, 2, 2,
                1, 1,
                0, 0, 0, 0, -1, -1, -1, -2, -2, -2, -2, -2, -2, -3, -3, -3, -3
            ];

            var rabbit_dir = '上' //当前兔子方向
            var up = new BABYLON.Vector3(0, 0, 0); //上
            var down = new BABYLON.Vector3(0, Math.PI, 0); //下
            var left = new BABYLON.Vector3(0, Math.PI * 1.5, 0); //左
            var right = new BABYLON.Vector3(0, Math.PI / 2, 0); //右

            var scene = new BABYLON.Scene(engine); //场景对象

            var transparent = new BABYLON.StandardMaterial("transparent", scene); //透明纹理
            transparent.diffuseColor = new BABYLON.Color3(0, 0, 0);
            transparent.alpha = 0;

            var anchor = new BABYLON.TransformNode("");
            var vrHelper = scene.createDefaultVRExperience();
            vrHelper.position = new BABYLON.Vector3(0, 20, -20); //vrhelp 内置相机坐标
            // var light = new BABYLON.DirectionalLight("dir01", new BABYLON.Vector3(5, -5, -5.0), scene);
            var light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, 1, 0), scene); //平行光灯光对象
            var camera = new BABYLON.ArcRotateCamera("camera1", Math.PI / 4, Math.PI / 2, 3, new BABYLON.Vector3(0, 20, -20), scene); //环绕相机对象
            camera.position = new BABYLON.Vector3(0, 20, -20); //环绕相机坐标
            camera.attachControl(canvas, true);
            window.skelton;
            window.mesh;
            var flag = 0;
            var skybox = BABYLON.MeshBuilder.CreateBox("skyBox", {
                size: 100.0
            }, scene); //天空盒子 （场景）
            var skyboxMaterial = new BABYLON.StandardMaterial("skyBox", scene);
            skyboxMaterial.backFaceCulling = false;
            skyboxMaterial.reflectionTexture = new BABYLON.CubeTexture("textures/skybox", scene);
            skyboxMaterial.reflectionTexture.coordinatesMode = BABYLON.Texture.SKYBOX_MODE;
            skyboxMaterial.diffuseColor = new BABYLON.Color3(0, 0, 0);
            skyboxMaterial.specularColor = new BABYLON.Color3(0, 0, 0);
            skybox.material = skyboxMaterial;
            skybox.position = new BABYLON.Vector3(0, 0, 0); //天空盒子位置
            // var ground = BABYLON.MeshBuilder.CreateGround("myGround", {
            //     width: 23,
            //     height: 23,
            //     subdivisions: 4
            // }, scene); //创建地板
            var ground = BABYLON.Mesh.CreateGround("myGround", 23, 23, 4, scene);

            var materialSphere1 = new BABYLON.StandardMaterial("textures1", scene);
            materialSphere1.ambientTexture = new BABYLON.Texture("textures/skybox_py.jpg", scene); //地板纹理图片
            ground.material = materialSphere1;
            ground.checkCollisions = true;
            vrHelper.enableTeleportation({ floorMeshName: "myGround" });
            var box = BABYLON.Mesh.CreateBox("wall", boxSize, scene); //墙模型
            box.material = new BABYLON.StandardMaterial("Mat", scene);
            box.material.diffuseTexture = new BABYLON.Texture("textures/wall3.jpg", scene); //墙模型纹理
            box.material.diffuseTexture.hasAlpha = true;
            box.position = new BABYLON.Vector3(0 * boxSize + offset, 0.5 * boxSize + 0.01, 0 * boxSize - offset); //墙模型初始位置
            box.checkCollisions = true;
            for (var index = 0; index < x_array.length; index++) {
                // 复制放置一堆墙模型
                var newInstance = box.createInstance("wall" + index);
                newInstance.checkCollisions = true;
                newInstance.ellipsoid = new BABYLON.Vector3(offset, offset, offset);
                newInstance.position.x = x_array[index] * boxSize + offset;
                newInstance.position.z = z_array[index] * boxSize - offset;
            }
            var box1 = BABYLON.Mesh.CreateBox("box1", boxSize, scene); //箱子模型1
            box1.material = new BABYLON.StandardMaterial("Mat", scene);
            box1.material.diffuseTexture = new BABYLON.Texture("textures/box.jpg", scene); //箱子模型纹理
            box1.material.diffuseTexture.hasAlpha = true;
            var box2 = box1.clone("box2"); //箱子模型2
            var box3 = box1.clone("box3"); //箱子模型3
            box1.position = new BABYLON.Vector3(1 * boxSize + offset, 0.5 * boxSize + 0.01, 2 * boxSize - offset); //箱子模型1初始位置
            box2.position = new BABYLON.Vector3(1 * boxSize + offset, 0.5 * boxSize + 0.01, 1 * boxSize - offset); //箱子模型2初始位置
            box3.position = new BABYLON.Vector3(1 * boxSize + offset, 0.5 * boxSize + 0.01, 0 * boxSize - offset); //箱子模型3初始位置
            box1.checkCollisions = true;
            box2.checkCollisions = true;
            box3.checkCollisions = true;
            var target1 = BABYLON.MeshBuilder.CreateGround("target1", {
                width: boxSize,
                height: boxSize,
                subdivisions: 4
            }, scene); //创建放置地板块1
            var materialSphere2 = new BABYLON.StandardMaterial("textures2", scene);
            materialSphere2.ambientTexture = new BABYLON.Texture("textures/grass.jpg", scene); //放置地板块纹理
            target1.material = materialSphere2;
            var target2 = target1.clone("target2"); //创建放置地板块2
            var target3 = target1.clone("target3"); //创建放置地板块3
            target1.position = new BABYLON.Vector3(2 * boxSize + offset, 0.01, 2 * boxSize - offset); //放置地板块1 初始位置
            target2.position = new BABYLON.Vector3(2 * boxSize + offset, 0.01, 1 * boxSize - offset); //放置地板块2 初始位置
            target3.position = new BABYLON.Vector3(2 * boxSize + offset, 0.01, 0 * boxSize - offset); //放置地板块3 初始位置
            target1.checkCollisions = true;
            target2.checkCollisions = true;
            target3.checkCollisions = true;

            var playgroundSize = 30;
                var font_size = 48;
            var font = "bold " + font_size + "px Arial";
            // Background
            var background = BABYLON.Mesh.CreatePlane("background", playgroundSize, scene, false);
            background.material = new BABYLON.StandardMaterial("background", scene);
            background.scaling.y = 0.5;
            background.position.z = playgroundSize / 2 - 0.5;
            background.position.y = playgroundSize / 4;
            background.receiveShadows = true;
            var backgroundTexture = new BABYLON.DynamicTexture("dynamic texture", 512, scene, true);


            backgroundTexture.drawText("使用步数："+runNum, null, null, font, "#000000", "transparent", true);
            backgroundTexture.hasAlpha = true
            background.material.diffuseTexture = backgroundTexture;
            background.material.backFaceCulling = false;

            BABYLON.SceneLoader.ImportMesh("Rabbit", "scenes/", "Rabbit.babylon", scene, function(newMeshes, particleSystems, skeletons) {
                // 加载兔子模型
                var rabbit = newMeshes[1];
                scene.beginAnimation(skeletons[0],0,70,true,1.0);
                rabbit.name = 'rabbit'
                var rabbit_box = BABYLON.MeshBuilder.CreateBox("rabbit_collision", {
                    size: 2.5
                }, scene); //兔子透明盒子
                rabbit_box.material = transparent //兔子透明盒子

                rabbit_box.checkCollisions = true; //盒子碰撞
                var manager = new BABYLON.GUI.GUI3DManager(scene); //官方的3dui管理器



                rabbit.scaling.scaleInPlace(0.05) //缩小兔子模型
                rabbit_box.position = new BABYLON.Vector3(2 * boxSize + offset, 0.5 * boxSize + 0.01, -1 * boxSize - offset) //兔子盒子位置
                rabbit_box.ellipsoid = new BABYLON.Vector3(offset , offset , offset);
                rabbit_box.ellipsoidOffset = new BABYLON.Vector3(0, 0, 0); //碰撞网格偏移量
                rabbit.position = new BABYLON.Vector3(2 * boxSize + offset, 0.01, -1 * boxSize - offset) //兔子位置
                rabbit_box.addChild(rabbit)
                console.log(rabbit)



                // Create app bar
                var appBar = new BABYLON.TransformNode(""); //轮换中心节点
                var panel = new BABYLON.GUI.PlanePanel(); //平板
                panel.margin = 0.2;
                panel.rows = 3;
                manager.addControl(panel); //添加平板为ui管理器控制子项
                panel.linkToTransformNode(appBar); //和节点链接
                panel.position = new BABYLON.Vector3(rabbit_box.position.x, rabbit_box.position.y + boxSize + 2, rabbit_box.position.z - boxSize + 0.5);
                var btnName = ["","左","", "下","", "上","", "右",""];
                var btns = [] //按钮组
                for (var index = 0; index < 9; index++) {
                    var button = new BABYLON.GUI.HolographicButton(btnName[index]);
                    btns.push(button)
                }
                btns.forEach(function(button, index) {
                    panel.addControl(button); //添加按钮为平板子项
                    if(btnName[index]==""){
                        button.isVisible =false;    
                    }
                    var text1 = new BABYLON.GUI.TextBlock();
                    text1.text = btnName[index];
                    text1.color = "white";
                    text1.fontSize = 90;
                    button.content = text1;
                    button.onPointerClickObservable.add(() => {
                    runNum ++;
                    var ctx = backgroundTexture.getContext();

                        var name = button.name //按钮名字
                        // console.log(name)
                        console.log(rabbit_box.position)
                        var distance = boxSize //移动距离
                        var oneframedistance = 0.1 //每次移动距离 （固定）
                        var flag = 0;
                        var flag2 = 0;
                        var flag3 = 0;
                        rabbit_box.onCollide = function(collidedMesh) {
                                var origin = new BABYLON.Vector3(rabbit_box.position.x, rabbit_box.position.y, rabbit_box.position.z);
                                var forward = new BABYLON.Vector3(0, 0, 1);
                                forward = vecToLocal(forward, rabbit_box);

                                var direction = forward.subtract(origin);
                                direction = BABYLON.Vector3.Normalize(direction);

                                var length = 100;

                                var ray = new BABYLON.Ray(origin, direction, length);
                                var hits = scene.multiPickWithRay(ray);
                                hits.forEach(function(hit) {
                                    if (hit.pickedMesh.name.indexOf('wall') != -1) {
                                        // 墙
                                    } else if (hit.pickedMesh.name.indexOf('box') != -1 && hit.distance < 1.3&&flag==0) {
                                        // 箱子
                                        var boxforwards

                                        var position = hit.pickedMesh.position;
                                        if (rabbit_dir == "上") {
                                            hit.pickedMesh.ellipsoid = new BABYLON.Vector3(offset , offset , offset);
                                            hit.pickedMesh.ellipsoidOffset = new BABYLON.Vector3(0, 0, 0); //碰撞网格偏移量
                                            boxforwards = new BABYLON.Vector3(0, 0, oneframedistance);
                                            position = new BABYLON.Vector3(position.x,position.y,position.z+boxSize);

                                        } else if (rabbit_dir == "下") {

                                            hit.pickedMesh.ellipsoid = new BABYLON.Vector3(offset , offset , offset);
                                            hit.pickedMesh.ellipsoidOffset = new BABYLON.Vector3(0, 0, 0); //碰撞网格偏移量
                                            boxforwards = new BABYLON.Vector3(0, 0, -oneframedistance);
                                            position = new BABYLON.Vector3(position.x,position.y,position.z-boxSize);

                                        } else if (rabbit_dir == "左") {

                                            hit.pickedMesh.ellipsoid = new BABYLON.Vector3(offset , offset , offset);
                                            hit.pickedMesh.ellipsoidOffset = new BABYLON.Vector3(0, 0, 0); //碰撞网格偏移量
                                            boxforwards = new BABYLON.Vector3(-oneframedistance, 0, 0);
                                            position = new BABYLON.Vector3(position.x-boxSize,position.y,position.z);

                                        } else if (rabbit_dir == "右") {

                                            hit.pickedMesh.ellipsoid = new BABYLON.Vector3(offset , offset , offset);
                                            hit.pickedMesh.ellipsoidOffset = new BABYLON.Vector3(0, 0, 0); //碰撞网格偏移量
                                            boxforwards = new BABYLON.Vector3(oneframedistance, 0, 0);
                                            position = new BABYLON.Vector3(position.x+boxSize,position.y,position.z);
                                        }
                                        var distance_sum = 0 //累计移动距离
                                        scene.registerBeforeRender(function() {
                                        
                                            if (distance_sum <= distance) {
                                                console.log('移动')
                                                flag = 1;
                                                flag3 = 1;
                                                boxforwards.negate();
                                                hit.pickedMesh.moveWithCollisions(boxforwards);
                                                distance_sum += oneframedistance

                                            }else{
                                                if(flag3==1){
                                                hitposition = hit.pickedMesh.position;
                                                if(Math.abs(hitposition.x-position.x)<0.5&&Math.abs(hitposition.y-position.y)<0.5&&Math.abs(hitposition.z-position.z)<0.5){
                                                    hit.pickedMesh.position = position;
                                                    flag3=0;
                                                }                                                    
                                                }

                                                flag=0;
                                            }
                                        });

                                    }

                                })

                            }
                            // 定时器动画
                        var forwards
                        var position2 = rabbit_box.position;
                        if (name == "上") {
                            rabbit_dir = "上"
                            rabbit_box.rotation = up
                            rabbit_box.ellipsoid = new BABYLON.Vector3(offset , offset , offset);
                            rabbit_box.ellipsoidOffset = new BABYLON.Vector3(0, 0, 0); //碰撞网格偏移量
                            forwards = new BABYLON.Vector3(0, 0, oneframedistance);
                            position2 = new BABYLON.Vector3(position2.x,position2.y,position2.z+boxSize);


                        } else if (name == "下") {
                            rabbit_dir = "下"
                            rabbit_box.rotation = down
                            rabbit_box.ellipsoid = new BABYLON.Vector3(offset , offset , offset);
                            rabbit_box.ellipsoidOffset = new BABYLON.Vector3(0, 0, 0); //碰撞网格偏移量
                            forwards = new BABYLON.Vector3(0, 0, -oneframedistance);
                            position2 = new BABYLON.Vector3(position2.x,position2.y,position2.z-boxSize);

                        } else if (name == "左") {
                            rabbit_dir = "左"
                            rabbit_box.rotation = left
                            rabbit_box.ellipsoid = new BABYLON.Vector3(offset , offset , offset);
                            rabbit_box.ellipsoidOffset = new BABYLON.Vector3(0, 0, 0); //碰撞网格偏移量
                            forwards = new BABYLON.Vector3(-oneframedistance, 0, 0);
                            position2 = new BABYLON.Vector3(position2.x-boxSize,position2.y,position2.z);

                        } else if (name == "右") {
                            rabbit_dir = "右"
                            rabbit_box.rotation = right
                            rabbit_box.ellipsoid = new BABYLON.Vector3(offset , offset , offset);
                            rabbit_box.ellipsoidOffset = new BABYLON.Vector3(0, 0, 0); //碰撞网格偏移量
                            forwards = new BABYLON.Vector3(oneframedistance, 0, 0);
                            position2 = new BABYLON.Vector3(position2.x+boxSize,position2.y,position2.z);

                        }


                            var distance_sum = 0 //累计移动距离
                            scene.registerBeforeRender(function() {
                                //跟随场景刷新移动 （比定时器+各种计算准确）

                                if (distance_sum <= distance) {
                                    ctx.clearRect(0, 0, 512, 512)
                                    backgroundTexture.drawText("使用步数："+runNum, null, null, font, "#000000", "transparent", true);
                                    flag2 = 1;
                                    forwards.negate();
                                    rabbit_box.moveWithCollisions(forwards);
                                    distance_sum += oneframedistance
                                    panel.position = new BABYLON.Vector3(rabbit_box.position.x, rabbit_box.position.y + boxSize + 2, rabbit_box.position.z - boxSize + 0.5);
                                }else{
                                    if(flag2==1){
                                     if(Math.abs(rabbit_box.position.x-position2.x)<0.5&&Math.abs(rabbit_box.position.y-position2.y)<0.5&&Math.abs(rabbit_box.position.z-position2.z)<0.5){
                                        // console.log(position2);
                                        rabbit_box.position = position2;
                                        panel.position = new BABYLON.Vector3(rabbit_box.position.x, rabbit_box.position.y + boxSize + 2, rabbit_box.position.z - boxSize + 0.5);
                                        flag2=0;

                                    }
                                       
                                    }
                                }
                            });

                    })
                })
                                var origin1 = new BABYLON.Vector3(target1.position.x, target1.position.y, target1.position.z);

                                var forward1 = new BABYLON.Vector3(0, 1, 0);
                                forward1 = vecToLocal(forward1, target1);

                                var direction1 = forward1.subtract(origin1);
                                direction1 = BABYLON.Vector3.Normalize(direction1);

                                var length = 10;

                                var ray = new BABYLON.Ray(origin1, direction1, length);

                                     scene.registerBeforeRender(function() {
                                        forward1.negate();
                                var hits = scene.multiPickWithRay(ray);
                                hits.forEach(function(hit) {
                                    if (hit.pickedMesh.name.indexOf('rabbit') != -1) {
                                        console.log(hit)
                                       }
                                    })

                                     });
                                                        

            });

            // vrHelper.onControllerMeshLoaded.add((ViveController) => {
            //     var controllerMesh = ViveController.mesh;
            //     ViveController.onSecondaryButtonStateChangedObservable.add(() => {
            //         // Trigger pressed event
            //     });
            // });

           
            // vrHelper.raySelectionPredicate = (mesh) => {
            //     console.log("1"+mesh.name);
            //     if (mesh.name.indexOf("Flags") !== -1) {
            //         return true;
            //     }
            //     return false;
            // };
            // vrHelper.meshSelectionPredicate = (mesh) => {
            //     console.log("2"+mesh.name);
            //     if (mesh.name.indexOf("Flags01") !== -1) {
            //         return true;
            //     }
            //     return false;
            // };
            // vrHelper.onNewMeshSelected.add((mesh) => {
            //     console.log("3"+mesh.name);
            // });
            return scene;
        }
        var scene = createScene();
        engine.runRenderLoop(function() {
            scene.render();
        });
        window.addEventListener("resize", function() {
            engine.resize();
        });
    </script>
</body>

</html>